<template>
  <div class="dashboard-container">
    <div class="app-container">
      <el-card>
        <el-tabs>
          <el-tab-pane label="角色管理">
            <el-row>
              <el-button
                icon="el-icon-circle-plus"
                size="mini"
                type="primary"
                @click="showDialog = true"
              >新增角色
              </el-button>
            </el-row>

            <el-table :data="list">
              <el-table-column label="序号" type="index" />
              <el-table-column label="角色名称" width="240" prop="name" />
              <el-table-column label="描述" prop="description" />
              <el-table-column label="操作">
                <!--作用域插槽-->
                <template v-slot="{ row }">
                  <el-button
                    size="mini"
                    type="success"
                    @click="assignPermission(row.id)"
                  >分配权限
                  </el-button>
                  <el-button
                    size="mini"
                    type="primary"
                    @click="editRole(row.id)"
                  >编辑
                  </el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    @click="delRoleById(row.id)"
                  >删除
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
            <el-row type="flex" justify="center" style="margin-top: 20px">
              <el-pagination
                :page-size="page.pagesize"
                :total="page.total"
                :current-page="page.page"
                layout="prev, pager, next, total"
                @current-change="changePage"
              />
            </el-row>
          </el-tab-pane>
          <el-tab-pane label="公司信息">
            <el-alert
              show-icon
              title="对公司名称、公司地址、营业执照、公司地区的更新，将使得公司资料被重新审核，请谨慎修改"
              type="info"
            />
            <el-form disabled label-width="120px" style="margin-top: 20px">
              <el-form-item label="公司名称">
                <el-input v-model="formData.name" style="width: 30%" />
              </el-form-item>
              <el-form-item label="公司地址">
                <el-input
                  v-model="formData.companyAddress"
                  style="width: 30%"
                />
              </el-form-item>
              <el-form-item label="邮箱">
                <el-input v-model="formData.mailbox" style="width: 30%" />
              </el-form-item>
              <el-form-item label="备注">
                <el-input
                  v-model="formData.remarks"
                  style="width: 30%"
                  type="textarea"
                />
              </el-form-item>
            </el-form>
          </el-tab-pane>
        </el-tabs>
      </el-card>
    </div>

    <el-dialog
      :title="`${roleForm.id ? '编辑角色' : '新增角色'}`"
      :visible="showDialog"
      @close="closeDialog"
    >
      <el-form
        ref="roleFormRef"
        label-width="100px"
        :model="roleForm"
        :rules="rules"
      >
        <el-form-item label="角色" prop="name">
          <el-input v-model="roleForm.name" />
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input v-model="roleForm.description" />
        </el-form-item>
      </el-form>
      <!-- 底部 -->
      <el-row slot="footer" type="flex" justify="center">
        <el-col :span="6">
          <el-button size="small" @click="closeDialog">取消</el-button>
          <el-button size="small" type="primary" @click="btnOK">确定</el-button>
        </el-col>
      </el-row>
    </el-dialog>
    <el-dialog
      :visible="isShowAssignPermission"
      title="分配权限"
      @close="closePermissionDialog"
    >
      <el-tree
        ref="permissionRef"
        :props="defaultProps"
        :data="permissionData"
        :show-checkbox="true"
        :default-expand-all="true"
        node-key="id"
        :default-checked-keys="checkedPermission"
        :check-strictly="true"
      />
      <template #footer>
        <el-row type="flex" justify="center">
          <el-button size="mini" @click="closePermissionDialog">取消</el-button>
          <el-button type="primary" @click="permissionOk">确认</el-button>
        </el-row>
      </template>
    </el-dialog>
  </div>
</template>

<script>
// 1、指定节点的key为数据的id
// 2、通过default-checked-keys指定选中的节点的key的列表
import {
  addRole,
  assignPerm,
  deleteRole,
  getCompanyInfo,
  getRoleDetail,
  getRoleList,
  updateRole
} from '@/api/setting'
import { mapGetters } from 'vuex'
import { getPermissionList } from '@/api/permission'
import { tranListToTreeData } from '@/utils'

export default {
  name: 'Setting',
  data() {
    return {
      currentId: null,
      checkedPermission: [],
      permissionData: [],
      defaultProps: {
        label: 'name'
      },
      isShowAssignPermission: false,
      roleForm: {
        name: '',
        description: ''
      },

      rules: {
        name: [
          {
            required: true,
            message: '角色名称不能为空'
          }
        ]
      },
      showDialog: false,
      list: [], // 承接服务器返回的列表数据，用于界面上展示
      page: {
        page: 1, // 当前的页码数
        pagesize: 2, // 每页多少条数据
        total: 0 // 记录总的页码条数
      },
      formData: {
        name: '',
        companyAddress: '',
        mailbox: '',
        remarks: ''
      }
    }
  },
  computed: {
    ...mapGetters(['companyId'])
  },
  created() {
    this.getRoleList()
    this.getCompanyDetailById()
  },
  methods: {
    closePermissionDialog() {
      this.isShowAssignPermission = false
      this.checkedPermission = []
    },
    async permissionOk() {
      // 拿到勾选之后的结果
      //   直接提交checkedPermission不可以，服务器端返回的当前角色对应的权限id列表
      //  可以通过getCheckedKeys 获取tree组件内部所有的选中的节点（节点的key组成的数组）
      await assignPerm({
        id: this.currentId,
        permIds: this.$refs.permissionRef.getCheckedKeys()
      })
      this.$message.success('修改角色对应的权限信息成功')
      // 提交完成需要关闭弹层清除数据
      this.closePermissionDialog()
    },
    // 点击了分配权限触发的方法
    async assignPermission(id) {
      // 点击的角色的id记录下来
      this.currentId = id
      // 获取所有的权限点，做默认的展示
      const res = tranListToTreeData(await getPermissionList(), '0')
      this.permissionData = res

      // 获取当前点击的角色对应的权限，tree组件里面进行勾选
      const { permIds } = await getRoleDetail(id)
      this.checkedPermission = permIds

      // 直接让弹层展示
      this.isShowAssignPermission = true
    },
    async btnOK() {
      //  执行更新或者新增的操作
      //  无论你是编辑或者新增，提交之前必须进行表单的校验
      //  1、校验表单
      await this.$refs.roleFormRef.validate()
      //  2、执行新增或者编辑的的操作(可以把数据提交服务器)
      if (this.roleForm.id) {
        //  如果id存在，那就是编辑（把当前编辑表单的数据直接提交到服务器即可）
        await updateRole(this.roleForm)
      } else {
        //  id不存在，那就是新增
        await addRole(this.roleForm)
      }
      this.$message.success(`${this.roleForm.id ? '编辑' : '新增'}角色`)
      //  重新拉取列表数据
      this.getRoleList()
      // 关闭弹层
      // this.showDialog = false
      this.closeDialog()
    },
    async getRoleList() {
      // 调用接口获取数据
      // 解构出rows和total数据
      const { rows, total } = await getRoleList(this.page)
      // console.log(res)
      this.list = rows
      this.page.total = total
    },
    changePage(newPage) {
      // 当前页码数发生变化的时候会触发
      // 接受的参数为最新的页码数
      // 修改参数之后重新请求
      this.page.page = newPage
      this.getRoleList()
    },
    async getCompanyDetailById() {
      // 如何在组件内部获取到vuex内部的字段
      this.formData = await getCompanyInfo(this.companyId)
    },
    async editRole(id) {
      // TODO: 请求接口数据，获取角色详情，填充弹出层
      this.roleForm = await getRoleDetail(id)
      // TODO: 获取到当前角色的详细信息，需要让表单做数据的回显
      // console.log(res)
      //  展示弹层
      this.showDialog = true
    },
    closeDialog() {
      // 实现了弹层的隐藏功能
      this.showDialog = false
      //   重置表单校验
      this.$refs.roleFormRef.resetFields()
      //  重置表单数据
      this.roleForm = {
        name: '',
        description: ''
      }
    },
    async delRoleById(id) {
      // 删除的时候先获取当前页面数据条数
      const len = this.list.length
      try {
        await this.$confirm('是否确认删除？')
        await deleteRole(id)
        this.$message.success('删除成功')

        // 如果删除之前数据条数为1，删除之后当前页面就没有数据了
        // 如果条数为1&&当前不在第一页的情况下，让页码自减之后再去获取列表数据
        // 防止删除当前页面最后一条数据页面出现空白
        if (len === 1 && this.page.page > 1) {
          this.page.page--
        }
        await this.getRoleList()
      } catch (e) {
        console.log(e)
      }
    }
  }
}

/**
 * 实现编辑功能：
 * 1、点击编辑按钮，弹出一个弹出层
 * 2、需要把当前点击的角色详细信息（通过角色id请求接口）再弹层里面做一个填充
 * 3、点击了确定的时候，需要把当前数据提交服务器端（请求接口），修改当前点击数据
 */

// 实现删除功能
// 1、点击删除的时候需要弹出一个确认弹层
// 2、点击了确定之后，再执行删除的操作
// 3、删除成功之后需要进行成功地提示
// 4、删除成功之后重新拉取列表数据

// 什么是深拷贝（复杂数据类型进行遍历，拷贝内部的基本值而不是引用地址）/什么是浅拷贝？
// js数据类型？简单数据类型/复杂的数据类型？
// 复杂的数据类型在栈中存储的仅仅是一个引用地址，如果说我们拷贝的时候，只拷贝了地址？修改拷贝之后的数据会影响之前的
// 进行深拷贝把里面的值拷贝出来，而不是引用地址

// 我们js数据类型有复杂数据类型还有基本数据类型，复杂数据类型存储的是地址
// 深拷贝：递归拷贝内部的基本值
// 浅拷贝：只拷贝了一层，深层次的数据拷贝过来的是一个地址

// 实现？
// 递归处理？如果基本值直接拷贝，如果是复杂数据类型，进行递归，遍历到基本值为止
// 循环引用问题？解决：我们会构建一个map对象，缓存已经拷贝过的复杂数据类型，如果递归的时候再遇到地址想同的数据，直接复用缓存的值不去递归

// 你们公司里面都是自己写深拷贝的吗？
// 我们项目一般会使用lodash第三方库

// 为什么使用第三方库？
// 第三方库做了很多兼容性的条件判断，使用更加安全

function get({ row }) {
  // console.log(obj.row)
  console.log(row)
}

get({
  row: [{}]
})
</script>

<style></style>
